/**
 * @Author: jichang
 * @Date: 2024/10/28 13:49:05
 */
#pragma once

#include <mutex>
#include <iostream>
#include <condition_variable>
#include <queue>
#include <memory>
#include <thread>
#include <string>

namespace messaging
{
    // 队列项基础====================
    struct message_base {
        virtual ~message_base() { }
    };

    // 继承自base的特化
    template<typename Msg>
    struct wrapped_message: message_base {
        explicit wrapped_message(Msg const& contents_):
            contents(contents_) { }
        Msg contents;
    };

    // 消息队列=====================
    class queue {
    public:
        template<typename T>
        void push(T const& msg) {
            std::lock_guard<std::mutex> lock(m);
            // 通过包装已经传递的信息，存储指针
            q.push(std::make_shared<wrapped_message<T>>(msg));
            c.notify_all();
        }

        std::shared_ptr<message_base> wait_pop() {
            std::unique_lock<std::mutex> lock(m);
            c.wait(lock, [&] {
                return !q.empty();
            }); // 当队列为空时等待
            // 弹出第一个返回
            std::shared_ptr<message_base> res = q.front();
            q.pop();
            return res; 
        }

    private:
        std::mutex m;
        std::condition_variable c;
        // 实际存储指向base类指针的队列
        std::queue<std::shared_ptr<message_base>> q;
    };
};

// void test_this_queue() {
//     using namespace messaging;
//     // wrapped_message<std::string> wsmg("this is a mesg");
//     queue simpq;
//     simpq.push("this is a msg"); // 自动类型推导
//     std::shared_ptr<message_base> res = simpq.wait_pop();
// }

